package com.atguigu.yygh.user.controller.user;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.common.exception.YyghException;
import com.atguigu.yygh.common.result.R;
import com.atguigu.yygh.common.util.JwtHelper;
import com.atguigu.yygh.model.user.UserInfo;
import com.atguigu.yygh.user.properties.WeixinProperties;
import com.atguigu.yygh.user.service.UserInfoService;
import com.atguigu.yygh.user.utils.HttpClientUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @author mgx
 * @version 1.0
 * @description: TODO
 * @date 2022/9/1 21:35
 */
@Controller
@RequestMapping("/user/userinfo/wx")
@Api(tags = {"微信登录相关服务管理"})
public class WeixinApiController {

    // 注入配置类
    @Autowired
    private WeixinProperties weixinProperties;

    @Autowired
    private UserInfoService userInfoService;

    @ApiOperation(value = "获取微信登录的相关参数")
    @GetMapping("/param")
    @ResponseBody
    public R getWeixinParam() throws UnsupportedEncodingException {
        String redirectUri = URLEncoder.encode(weixinProperties.getRedirecturi(), "UTF-8");
        Map<String, Object> map = new HashMap<>();
        map.put("appid", weixinProperties.getAppid());
        map.put("scope", "snsapi_login");
        map.put("redirectUri", redirectUri);
        map.put("state", System.currentTimeMillis() + "");
        return R.ok().data(map);
    }

    @ApiOperation(value = "用于微信服务器的回调接口")
    @GetMapping("/callback")
    public String callback(String code, String state) throws Exception {
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder append = stringBuilder.append("https://api.weixin.qq.com/sns/oauth2/access_token?")
                .append("appid=%s")
                .append("&secret=%s")
                .append("&code=%s")
                .append("&grant_type=authorization_code");
        String format = String.format(append.toString(), weixinProperties.getAppid(), weixinProperties.getAppsecret(), code);
        String result = HttpClientUtils.get(format);
        // 把format换成json对象，从中获取openid和access_token
        JSONObject jsonObject = JSONObject.parseObject(result);
        System.out.println(jsonObject);
        String access_token = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");

        // 先从数据库根据openid查询是不是首次微信登录
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("openid", openid);
        UserInfo user = userInfoService.getOne(queryWrapper);
        if (user == null) {
            // 首次微信登录
            // 需要携带access_token和openid给服务器端获取用户信息
            StringBuilder builder = new StringBuilder();
            StringBuilder builder1 = builder.append("https://api.weixin.qq.com/sns/userinfo")
                    .append("?access_token=%s")
                    .append("&openid=%s");
            String format1 = String.format(builder1.toString(), access_token, openid);
            // 发送请求给微信服务器获取用户信息
            String res = HttpClientUtils.get(format1);
            // 转化为Json格式【Fastjson/gson】
            JSONObject jsonObject1 = JSONObject.parseObject(res);
            System.out.println(jsonObject1);
            String nickname = jsonObject1.getString("nickname");
            user = new UserInfo();
            user.setNickName(nickname);
            user.setOpenid(openid);
            user.setStatus(1);
            userInfoService.save(user);
        }

        // 验证
        if(user.getStatus() == 0) {
            throw new YyghException(20001, "当前用户已经被锁定");
        }
        // 6.返回用户数据
        Map<String, String> map = new HashMap<String, String>();

        // 检验手机号是否为空，为空：首次微信登录需要绑定手机号,返回给前端一个openid以作判断
        if(StringUtils.isEmpty(user.getPhone())) {
            map.put("openid", openid);
        }else {
            // 说明绑定过手机号了, 正常微信登录即可
            map.put("openid", "");
        }

        // 设置返回值
        String name = user.getName();
        if(StringUtils.isEmpty(name)) {
            name = user.getNickName();
        }
        if (StringUtils.isEmpty(name)) {
            name = user.getPhone();
        }
        map.put("name", name);
        String token = JwtHelper.createToken(user.getId(), name);
        map.put("token", token);
        // 重定向到静态路由页面
        return "redirect:http://localhost:3000/weixin/callback?token="+map.get("token")+ "&openid="+map.get("openid")+"&name="+URLEncoder.encode(map.get("name"),"utf-8");
    }
}
